// @author caoshi
// @date 2022/12/1 9:20
// @since 1.0
// 数组指针和指针数组的使用

/*
	数组指针: 首先是一个指针, 存储一个数组的地址
		*[len]Type

	指针数组: 首先是一个数组, 存储的数据类型是指针
		[len]*Type

	*[5]float64 存储5个浮点型数据的数组指针
	*[3]string	存储3个字符串数据的数组指针
	[3]*string	存储3个字符串指针的数组
	[5]*float64	存储5个浮点数据指针的数组
	*[5]*float64 数组指针 存储5个浮点型指针地址的数组指针
	*[3]*string	 数组指针 存储3个字符串的指针地址的数组指针
	**[4]string	 数组指针 存储4个字符串数据的数组的指针的指针

	**[4]*string 指针 存储了4个字符串的指针地址的数组的指针的指针

*/

package main

import "fmt"

func main() {
	// 1. 创建一个普通的数组
	arr1 := [4]int{1, 2, 3, 4}
	fmt.Println(arr1) // [1 2 3 4]

	// 2. 创建一个指针存储arr1的地址
	var p1 *[4]int
	p1 = &arr1
	fmt.Println(p1) // &[1 2 3 4]
	// 短声明
	p2 := &arr1
	fmt.Println(p2)         // &[1 2 3 4]
	fmt.Printf("%p\n", p1)  // 0xc0000121c0
	fmt.Printf("%p\n", &p1) // 0xc000006030 指针p1自己的地址

	// 通过数组指针操作数组元素
	(*p1)[0] = 100    // 将数组arr1的第一个元素修改为100
	fmt.Println(arr1) // [100 2 3 4]
	// 简写方式
	p1[0] = 200
	fmt.Println(arr1) // [200 2 3 4]

	fmt.Println("================================")
	/*****************************************************************************************************************/
	// 指针数组: 数组存储的数据类型是指针
	a := 1
	b := 2
	c := 3
	d := 4
	arr2 := [4]int{a, b, c, d}
	arr3 := [4]*int{&a, &b, &c, &d}
	fmt.Println(arr2)
	fmt.Println(arr3)
	// 修改arr2第一个元素的值
	arr2[0] = 100
	fmt.Println(arr2) // [100 2 3 4]
	fmt.Println(a)    // 1 a的值保持不变
	*arr3[0] = 200
	fmt.Println(arr2) // [100 2 3 4] arr2的第一个元素并没有改变说明存储的是值
	fmt.Println(arr3)
	fmt.Println(a) // a的值被修改了 因为 arr3[0] 是指向a的指针, 通过解引用修改了值

	b = 1000
	fmt.Println(arr2) // [100 2 3 4]
	fmt.Println(arr3)
	for i := range arr3 {
		fmt.Println(*arr3[i])
	}

}
